<template>
	<view class="ai-chat-page">
		<!-- 页面头部 -->
		<view class="page-header">
			<view class="header-left" @click="goBack">
				<text class="back-icon">←</text>
				<text class="back-text">返回</text>
			</view>
			<view class="header-center">
				<text class="page-title">🤖 AI助手</text>
			</view>
			<view class="header-right">
				<text class="clear-btn" @click="clearMessages">清空</text>
			</view>
		</view>

		<!-- 聊天内容区域 -->
		<scroll-view class="chat-content" scroll-y="true" :scroll-top="scrollTop" :scroll-into-view="scrollIntoView">
			<view class="message-list">
				<!-- 欢迎消息 -->
				<view class="message ai-message" v-if="messages.length === 0">
					<view class="message-avatar">🤖</view>
					<view class="message-content">
						<text class="message-text">你好！我是AI助手，有什么可以帮助你的吗？</text>
					</view>
				</view>

				<!-- 消息列表 -->
				<view v-for="(message, index) in messages" :key="index" 
					:id="'msg-' + index"
					class="message" :class="message.type + '-message'">
					<view class="message-avatar">
						<image v-if="message.type === 'user' && userInfo?.avatar" 
							:src="getAvatarUrl(userInfo.avatar)" 
							class="avatar-img" />
						<text v-else>{{ message.type === 'user' ? '👤' : '🤖' }}</text>
					</view>
					<view class="message-content">
						<!-- 用户消息使用普通文本 -->
						<text v-if="message.type === 'user'" class="message-text">{{ message.content }}</text>
						<!-- AI消息支持Markdown和流式显示 -->
						<view v-else class="message-text ai-content markdown-content" 
							v-html="message.renderedContent || message.content">
						</view>
						<text class="message-time">{{ message.time }}</text>
					</view>
				</view>

				<!-- AI思考过程 -->
				<view class="message ai-message" v-if="thinkingProcess">
					<view class="message-avatar">🤖</view>
					<view class="message-content">
						<view class="section-title">
							<text class="title-icon">💭</text>
							<text class="title-text">AI思考过程</text>
							<!-- 只在初始思考状态（无答案内容时）显示加载动画 -->
							<view class="thinking-dots" v-if="!streamingContent">
								<view class="dot"></view>
								<view class="dot"></view>
								<view class="dot"></view>
							</view>
						</view>
						<view class="thinking-content">
							<text class="thinking-text" :class="{ 'thinking-text-small': streamingContent }">{{ thinkingProcess }}</text>
						</view>
					</view>
				</view>

				<!-- AI回答内容 -->
				<view class="message ai-message" v-if="streamingContent" id="streaming-msg">
					<view class="message-avatar">🤖</view>
					<view class="message-content">
						<view class="section-title">
							<text class="title-icon">💡</text>
							<text class="title-text">AI回答</text>
							<!-- 回答阶段显示加载动画 -->
							<view class="thinking-dots" v-if="isStreaming">
								<view class="dot"></view>
								<view class="dot"></view>
								<view class="dot"></view>
							</view>
						</view>
						<view class="streaming-content markdown-content" 
							v-html="streamingContent">
						</view>
					</view>
				</view>
			</view>
		</scroll-view>

		<!-- 输入区域 -->
		<view class="chat-input-area">
			<view class="input-container">
				<input class="chat-input" 
					v-model="inputText" 
					placeholder="输入你的问题..." 
					:disabled="isProcessing"
					@confirm="sendMessage" 
					confirm-type="send" />
				<view class="send-btn" 
					:class="{ 
						'send-btn-active': inputText.trim() && !isProcessing,
						'send-btn-disabled': isProcessing
					}" 
					@click="sendMessage">
					<text class="send-icon" v-if="!isProcessing">➤</text>
					<view v-else class="loading-spinner"></view>
				</view>
			</view>
		</view>
	</view>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { marked } from 'marked';
import { baseURL, getAiApiUrl } from '@/utils/config';
import { userInfo } from '@/stores/user';

// 定义消息接口
interface Message {
	type: 'user' | 'ai';
	content: string;
	time: string;
	renderedContent?: string;
}

// 响应式数据
const messages = ref<Message[]>([]);
const inputText = ref('');
const scrollTop = ref(0);
const scrollIntoView = ref('');

// 流式处理相关状态
const thinkingProcess = ref(''); // 思考过程内容
const isStreaming = ref(false);
const streamingContent = ref('');
const streamBuffer = ref('');
const isInThinkTag = ref(false); // 标记是否在<think>标签内

// 计算属性：是否正在处理中（等待响应或流式回答）
const isProcessing = computed(() => isStreaming.value || thinkingProcess.value !== '');

// WebSocket连接
const socketTask = ref<any>(null);

// 页面参数
const pageContext = ref<Record<string, any>>({});
const getAvatarUrl = (avatar : string) => {
	if (!avatar) return '';
	// 如果已经是完整URL，直接返回
	if (avatar.startsWith('http')) {
		return avatar;
	}
	// 如果是相对路径，拼接baseURL
	return avatar.startsWith('/') ? baseURL + avatar : baseURL + '/' + avatar;
}

// 页面加载时获取参数
onLoad((options: any) => {
	console.log('📄 [AI Chat] 页面加载，参数:', options);
	
	// 获取传递的上下文参数
	if (options.context) {
		try {
			pageContext.value = JSON.parse(decodeURIComponent(options.context));
			console.log('📋 [AI Chat] 解析上下文:', pageContext.value);
		} catch (error) {
			console.error('❌ [AI Chat] 解析上下文失败:', error);
		}
	}
	
	// 如果有初始问题，自动发送
	if (options.question) {
		const question = decodeURIComponent(options.question);
		inputText.value = question;
		nextTick(() => {
			sendMessage();
		});
	}
});

// 组件挂载时配置Marked.js
onMounted(() => {
	if (typeof marked !== 'undefined') {
		try {
			marked.setOptions({
				breaks: false,
				gfm: true,
				tables: true,
				pedantic: false
			});
			console.log('✅ [AI Chat] Marked.js配置成功');
		} catch (error) {
			console.warn('⚠️ [AI Chat] Marked.js配置失败:', error);
		}
	}
});

// 组件卸载时清理WebSocket连接
onUnmounted(() => {
	if (socketTask.value) {
		socketTask.value.close();
		socketTask.value = null;
	}
});

// 返回上一页
const goBack = () => {
	uni.navigateBack();
};

// 发送消息
const sendMessage = async () => {
	if (!inputText.value.trim() || isProcessing.value) {
		return;
	}

	const userMessage: Message = {
		type: 'user',
		content: inputText.value.trim(),
		time: formatTime(new Date())
	};

	messages.value.push(userMessage);
	const question = inputText.value.trim();
	inputText.value = '';

	// 立即显示思考状态
	thinkingProcess.value = 'AI正在思考中...';
	isStreaming.value = false;
	streamBuffer.value = '';
	streamingContent.value = '';
	isInThinkTag.value = false;

	// 滚动到底部
	scrollToBottom();

	try {
		// 构建系统消息
		const systemMessage = `你是一个专业的AI助手。当前上下文信息：${JSON.stringify(pageContext.value)}

请根据用户的问题提供准确、有用的回答。

**重要格式要求**：
- 请使用标准Markdown格式回答
请确保回答结构清晰，便于阅读。`;

		// 调用WebSocket流式接口
		await callStreamAPI(question, systemMessage);
	} catch (error) {
		console.error('❌ [AI Chat] 发送消息失败:', error);
		thinkingProcess.value = '';
		addErrorMessage('发送消息失败，请重试');
	}
};

// 调用WebSocket流式API
const callStreamAPI = async (prompt: string, systemMessage: string) => {
	const wsUrl = getAiApiUrl('/api/ollama/chat-ws').replace('http://', 'ws://').replace('https://', 'wss://');
	
	socketTask.value = uni.connectSocket({
		url: wsUrl,
		success: () => {
			console.log('✅ [AI Chat] WebSocket连接请求已发送');
		},
		fail: (error: any) => {
			console.error('❌ [AI Chat] WebSocket连接失败:', error);
			thinkingProcess.value = '';
			addErrorMessage('WebSocket连接失败，请检查网络');
		}
	});
	
	socketTask.value.onOpen(() => {
		const message = JSON.stringify({
			prompt: prompt,
			systemMessage: systemMessage
		});
		
		socketTask.value.send({
			data: message,
			success: () => {
				console.log('✅ [AI Chat] 消息已发送');
			},
			fail: (error: any) => {
				console.error('❌ [AI Chat] 消息发送失败:', error);
				thinkingProcess.value = '';
				addErrorMessage('消息发送失败');
			}
		});
	});
	
	socketTask.value.onMessage((res: any) => {
		try {
			const message = JSON.parse(res.data);
			handleWebSocketMessage(message);
		} catch (error) {
			console.error('❌ [AI Chat] 解析消息失败:', error);
		}
	});
	
	socketTask.value.onError((error: any) => {
		console.error('❌ [AI Chat] WebSocket错误:', error);
		thinkingProcess.value = '';
		isStreaming.value = false;
		addErrorMessage('WebSocket连接出错');
	});
	
	socketTask.value.onClose(() => {
		console.log('🔌 [AI Chat] WebSocket连接已关闭');
		socketTask.value = null;
	});
};

// 处理WebSocket消息
const handleWebSocketMessage = (message: any) => {
	switch (message.type) {
		case 'connected':
			console.log('✅ [AI Chat] WebSocket连接确认');
			break;
			
		case 'thinking':
			// 忽略thinking消息，使用<think>标签方式处理
			break;
			
		case 'chunk':
			// 收到第一个chunk时，初始化状态
			if (!isStreaming.value) {
				isStreaming.value = true;
				streamBuffer.value = '';
				streamingContent.value = '';
				thinkingProcess.value = '';
				isInThinkTag.value = false;
			}
			
			// 累加流式数据
			streamBuffer.value += message.data;
			
			// 解析<think>标签
			processThinkTags();
			
			nextTick(() => {
				scrollToBottom();
			});
			break;
			
		case 'done':
			// 最后一次解析，确保完整
			processThinkTags();
			
			// 移除<think>标签，只保存答案内容
			let finalContent = streamBuffer.value.replace(/<think>[\s\S]*?<\/think>/gi, '').trim();
			
			messages.value.push({
				type: 'ai',
				content: finalContent,
				renderedContent: marked.parse(finalContent) as string,
				time: formatTime(new Date())
			});
			
			// 清理流式状态，但保留思考内容
			isStreaming.value = false;
			streamBuffer.value = '';
			streamingContent.value = '';
			isInThinkTag.value = false;
			// 注意：不清空thinkingProcess，让它保留在界面上
			
			// 延迟清空思考内容，让用户看到完整过程
			setTimeout(() => {
				thinkingProcess.value = '';
			}, 1000);
			
			scrollToBottom();
			break;
			
		case 'error':
			thinkingProcess.value = '';
			isStreaming.value = false;
			addErrorMessage(message.data || '服务器处理失败');
			
			if (socketTask.value) {
				socketTask.value.close();
				socketTask.value = null;
			}
			break;
	}
};

// 解析并处理<think>标签
const processThinkTags = () => {
	let content = streamBuffer.value;
	
	// 检测<think>开始标签
	const thinkStartMatch = content.match(/<think>/i);
	if (thinkStartMatch && !isInThinkTag.value) {
		isInThinkTag.value = true;
		// 移除<think>标签，保留后面的内容
		content = content.substring(thinkStartMatch.index! + thinkStartMatch[0].length);
		streamBuffer.value = content;
	}
	
	// 检测</think>结束标签
	const thinkEndMatch = content.match(/<\/think>/i);
	if (thinkEndMatch && isInThinkTag.value) {
		// 提取思考内容
		const thinkContent = content.substring(0, thinkEndMatch.index).trim();
		if (thinkContent) {
			thinkingProcess.value = thinkContent;
		}
		
		// 结束思考标签
		isInThinkTag.value = false;
		
		// 保留</think>后面的内容作为答案
		content = content.substring(thinkEndMatch.index! + thinkEndMatch[0].length).trim();
		streamBuffer.value = content;
	}
	
	// 根据当前状态更新显示内容
	if (isInThinkTag.value) {
		// 在思考标签内，更新思考内容
		thinkingProcess.value = content;
		streamingContent.value = '';
	} else {
		// 在思考标签外，渲染答案内容
		if (content) {
			streamingContent.value = marked.parse(content) as string;
		}
	}
};

// 添加错误消息
const addErrorMessage = (errorText: string) => {
	const errorMessage: Message = {
		type: 'ai',
		content: errorText,
		time: formatTime(new Date())
	};
	messages.value.push(errorMessage);
	scrollToBottom();
};

// 清空聊天记录
const clearMessages = () => {
	uni.showModal({
		title: '确认清空',
		content: '确定要清空所有聊天记录吗？',
		success: (res) => {
			if (res.confirm) {
				messages.value = [];
				thinkingProcess.value = '';
				isStreaming.value = false;
				streamBuffer.value = '';
				streamingContent.value = '';
			}
		}
	});
};

// 格式化时间
const formatTime = (date: Date): string => {
	const hours = date.getHours().toString().padStart(2, '0');
	const minutes = date.getMinutes().toString().padStart(2, '0');
	return `${hours}:${minutes}`;
};

// 滚动到底部
const scrollToBottom = () => {
	nextTick(() => {
		scrollTop.value = scrollTop.value + 100000;
		if (isStreaming.value) {
			scrollIntoView.value = 'streaming-msg';
		} else if (messages.value.length > 0) {
			scrollIntoView.value = 'msg-' + (messages.value.length - 1);
		}
	});
};
</script>

<style scoped lang="scss">
.ai-chat-page {
	display: flex;
	flex-direction: column;
	height: 100vh;
	background: #f5f5f5;
}

/* 页面头部 */
.page-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 24rpx 32rpx;
	background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
	box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
}

.header-left {
	display: flex;
	align-items: center;
	cursor: pointer;
}

.back-icon {
	font-size: 40rpx;
	color: #fff;
	margin-right: 8rpx;
}

.back-text {
	font-size: 28rpx;
	color: #fff;
}

.header-center {
	flex: 1;
	text-align: center;
}

.page-title {
	font-size: 32rpx;
	font-weight: 600;
	color: #fff;
}

.header-right {
	width: 100rpx;
	text-align: right;
}

.clear-btn {
	font-size: 28rpx;
	color: #fff;
	cursor: pointer;
}

/* 聊天内容区域 */
.chat-content {
	flex: 1;
	padding: 24rpx;
	overflow-y: auto;
}

.message-list {
	min-height: 100%;
}

.message {
	display: flex;
	margin-bottom: 32rpx;
	align-items: flex-start;
}

.user-message {
	flex-direction: row-reverse;
	justify-content: flex-start;
}

.message-avatar {
	width: 64rpx;
	height: 64rpx;
	border-radius: 32rpx;
	background: #f0f0f0;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 32rpx;
	flex-shrink: 0;
	overflow: hidden;
}

.avatar-img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.user-message .message-avatar {
	margin-left: 16rpx;
	margin-right: 24rpx;
}

.ai-message .message-avatar {
	margin-right: 16rpx;
}

.message-content {
	flex: 0 1 auto;
	max-width: 70%;
	min-width: 0;
}


.title-icon {
	font-size: 24rpx;
	margin-right: 8rpx;
}

.title-text {
	font-size: 24rpx;
	font-weight: 600;
	color: #667eea;
}

.message-text {
	display: inline-block;
	padding: 20rpx 24rpx;
	border-radius: 16rpx;
	font-size: 28rpx;
	line-height: 1.6;
	word-wrap: break-word;
}

.user-message .message-text {
	background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
	color: #fff;
}

.ai-message .message-text {
	background: #fff;
	color: #333;
	box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}

.message-time {
	display: block;
	margin-top: 8rpx;
	font-size: 20rpx;
	color: #999;
}

.user-message .message-time {
	text-align: right;
}

/* 思考状态 */
.thinking-content {
	padding: 20rpx 24rpx;
	background: #fff;
	border-radius: 16rpx;
	box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}

/* 标题中的加载动画布局 */
.section-title {
	display: flex;
	align-items: center;
	margin-bottom: 12rpx;
	padding: 8rpx 12rpx;
	background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%);
	border-radius: 8rpx;
	border-left: 4rpx solid #667eea;
	gap: 8rpx;
}

.thinking-text {
	font-size: 28rpx;
	color: #666;
	line-height: 1.6;
	white-space: pre-wrap;
	word-break: break-word;
	transition: font-size 0.3s ease;
}

.thinking-text-small {
	font-size: 24rpx;
	color: #999;
}

/* 思考加载动画 - 跳动的点 */
.thinking-dots {
	display: flex;
	align-items: center;
	gap: 6rpx;
}

.thinking-dots .dot {
	width: 8rpx;
	height: 8rpx;
	border-radius: 50%;
	background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
	animation: dotBounce 1.4s infinite ease-in-out both;
}

.thinking-dots .dot:nth-child(1) {
	animation-delay: -0.32s;
}

.thinking-dots .dot:nth-child(2) {
	animation-delay: -0.16s;
}

@keyframes dotBounce {
	0%, 80%, 100% {
		transform: scale(0);
		opacity: 0.5;
	}
	40% {
		transform: scale(1);
		opacity: 1;
	}
}

/* 流式内容 */
.streaming-content {
	padding: 20rpx 24rpx;
	background: #fff;
	border-radius: 16rpx;
	box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
	animation: pulse 1.5s ease-in-out infinite;
}

@keyframes pulse {
	0%, 100% { opacity: 1; }
	50% { opacity: 0.8; }
}

/* Markdown样式 */
.markdown-content {
	font-size: 28rpx;
	line-height: 1.8;
	color: #333;
}

.markdown-content ::v-deep h1,
.markdown-content ::v-deep h2,
.markdown-content ::v-deep h3 {
	margin: 24rpx 0 16rpx;
	font-weight: 600;
	color: #333;
}

.markdown-content ::v-deep code {
	padding: 4rpx 8rpx;
	background: #f5f5f5;
	border-radius: 4rpx;
	font-family: 'Courier New', monospace;
	font-size: 24rpx;
}

.markdown-content ::v-deep pre {
	padding: 20rpx;
	background: #f5f5f5;
	border-radius: 8rpx;
	overflow-x: auto;
	margin: 16rpx 0;
}

/* 输入区域 */
.chat-input-area {
	padding: 24rpx;
	background: #fff;
	border-top: 1px solid #e0e0e0;
}

.input-container {
	display: flex;
	align-items: center;
	gap: 16rpx;
}

.chat-input {
	flex: 1;
	padding: 20rpx 24rpx;
	background: linear-gradient(#fff, #fff) padding-box,
	            linear-gradient(135deg, #667eea 0%, #764ba2 25%, #f093fb 50%, #4facfe 75%, #667eea 100%) border-box;
	border-radius: 48rpx;
	font-size: 28rpx;
	border: 3px solid transparent;
	box-shadow: 0 4rpx 20rpx rgba(102, 126, 234, 0.2),
	            0 0 30rpx rgba(102, 126, 234, 0.1);
	transition: all 0.3s ease;
	background-size: 100% 100%, 200% 200%;
	animation: gradientShift 3s ease infinite;
}

.chat-input:focus {
	outline: none;
	box-shadow: 0 8rpx 30rpx rgba(102, 126, 234, 0.4),
	            0 0 40rpx rgba(118, 75, 162, 0.3),
	            0 0 0 4rpx rgba(102, 126, 234, 0.15);
}

.send-btn {
	width: 80rpx;
	height: 80rpx;
	border-radius: 40rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	background: #ddd;
	transition: all 0.3s;
	position: relative;
	overflow: hidden;
}

.send-btn-active {
	/* Apple Intelligence风格的动态渐变 */
	background: linear-gradient(135deg, 
		#667eea 0%, 
		#764ba2 25%, 
		#f093fb 50%, 
		#4facfe 75%, 
		#667eea 100%);
	background-size: 200% 200%;
	animation: gradientShift 3s ease infinite;
	box-shadow: 0 4rpx 20rpx rgba(102, 126, 234, 0.4),
	            0 8rpx 40rpx rgba(118, 75, 162, 0.3);
	cursor: pointer;
}

.send-btn-active:active {
	transform: scale(0.95);
	box-shadow: 0 2rpx 10rpx rgba(102, 126, 234, 0.3);
}

.send-btn-disabled {
	opacity: 0.6;
	cursor: not-allowed;
}

.send-icon {
	font-size: 36rpx;
	color: #fff;
}

.loading-spinner {
	width: 32rpx;
	height: 32rpx;
	border: 4rpx solid transparent;
	border-radius: 50%;
	position: relative;
	animation: spin 1s linear infinite;
}

.loading-spinner::before {
	content: '';
	position: absolute;
	top: -4rpx;
	left: -4rpx;
	right: -4rpx;
	bottom: -4rpx;
	border-radius: 50%;
	border: 4rpx solid transparent;
	/* 使用与思考点点相同的渐变色 */
	border-top-color: #667eea;
	border-right-color: rgba(102, 126, 234, 0.7);
	border-bottom-color: rgba(118, 75, 162, 0.5);
	border-left-color: rgba(118, 75, 162, 0.3);
}

@keyframes spin {
	to { transform: rotate(360deg); }
}

/* AI科技感渐变动画 */
@keyframes gradientShift {
	0% {
		background-position: 0% 50%;
	}
	50% {
		background-position: 100% 50%;
	}
	100% {
		background-position: 0% 50%;
	}
}
</style>
